<script setup lang="tsx">
import { onMounted, reactive, ref, watch } from 'vue'
import { useI18n } from '@/hooks/web/useI18n'
import {
  ElButton,
  ElCheckbox,
  ElDivider,
  ElForm,
  ElFormItem,
  ElImage,
  ElLink,
  ElTabPane,
  ElTabs,
  FormInstance,
  FormRules,
  TabsPaneContext
} from 'element-plus'
import {
  getLoginUserInfoApi,
  getUserRouterInfoApi,
  loginApi,
  sendMobileCodeApi,
  verifyCodeApi
} from '@/api/login'
import { useUserStore } from '@/store/modules/user'
import { useAppStore } from '@/store/modules/app'
import { usePermissionStore } from '@/store/modules/permission'
import type { RouteLocationNormalizedLoaded, RouteRecordRaw } from 'vue-router'
import { useRouter } from 'vue-router'
import { LoginType, RememberPasswordType, UserLoginType } from '@/api/login/types'
import { Icon } from '@/components/Icon'
import { sm3Encrypt } from '@/utils/crypto'
import { useStorage } from '@/hooks/web/useStorage'
import { useDesign } from '@/hooks/web/useDesign'
import { Iphone, Key, Lock, User } from '@element-plus/icons-vue'
import { unlockScreenApi } from '@/api/system/user'
import { UnlockScreen } from '@/api/system/user/types'
import { getSystemUserSettingApi } from '@/api/system/userSetting'
import { getSystemSettingApi } from '@/api/system/setting'

const { getStorage, setStorage, removeStorage } = useStorage('localStorage')

const userStore = useUserStore()
const appStore = useAppStore()

const permissionStore = usePermissionStore()

const { currentRoute, addRoute, push } = useRouter()
const { t } = useI18n()

const iconSize = 30

const remember = ref(false)

const loading = ref(false)

const iconColor = '#999'

const hoverColor = 'var(--el-color-primary)'

const redirect = ref<string>('')

watch(
  () => currentRoute.value,
  (route: RouteLocationNormalizedLoaded) => {
    redirect.value = route?.query?.redirect as string
  },
  {
    immediate: true
  }
)

const remainderTime = reactive({
  countdown: false,
  seconds: 60,
  buttonMessage: '获取验证码'
})

const getShortMessageVerifyCode = async (loginFormRef: FormInstance) => {
  await loginFormRef.validateField('mobile', async (isValid) => {
    if (isValid) {
      remainderTime.countdown = true
      remainderTime.buttonMessage = '59秒后重新获取'
      await sendMobileCodeApi(loginForm.mobile)
      const interval = setInterval(() => {
        if (remainderTime.seconds > 1) {
          remainderTime.seconds-- // 每次间隔减少1
          remainderTime.buttonMessage = remainderTime.seconds + '秒后重新获取'
        } else {
          clearInterval(interval) // 当倒计时结束时清除定时器
          remainderTime.buttonMessage = '请重新获取'
          remainderTime.countdown = false
          remainderTime.seconds = 60
        }
      }, 1000) // 设置每秒更新一次
    }
  })
}
const loginType = reactive<LoginType>({
  openVerificationCode: false,
  loginWay: []
})
const imageSrc = ref<string>('')
const getVerifyCode = async () => {
  const systemSetting = appStore.getSystemSetting
  loginType.openVerificationCode = systemSetting.openVerificationCode
  if (systemSetting.openVerificationCode) {
    const res = await verifyCodeApi()
    loginForm.verificationCodeKey = res.data.verificationCodeKey
    loginForm.verificationCode = res.data.verificationCode
    imageSrc.value = res.data.imageData
  }
}
const passwordLoginFormRef = ref<FormInstance>()
const mobileLoginFormRef = ref<FormInstance>()
// 登录
const login = async (loginFormRef: FormInstance) => {
  await loginFormRef.validate(async (isValid) => {
    if (isValid) {
      loading.value = true
      try {
        const loginParams: UserLoginType = Object.assign({}, loginForm)
        loginParams.loginPwd = sm3Encrypt(loginParams.loginPwd.trim())
        loginParams.loginWay = activeName.value
        const res = await loginApi(loginParams)
        if (res && res.code == 200) {
          if (remember.value) {
            const rememberPassword: RememberPasswordType = {
              userName: loginForm.userName,
              loginPwd: loginForm.loginPwd
            }
            setStorage('rememberPassword', rememberPassword)
          } else {
            removeStorage('rememberPassword')
          }
          userStore.setToken('Bearer ' + res.data)
          const userRes = await getLoginUserInfoApi()
          userStore.setUserInfo(userRes.data)
          await getUserRouterInfo()
          await getSystemUserSetting()
          await unlockScreen()
        } else {
          await getVerifyCode()
        }
      } finally {
        loading.value = false
      }
    }
  })
}
const unlockScreen = async () => {
  console.log('loginForm=====', loginForm.loginPwd)
  const params: UnlockScreen = {
    password: sm3Encrypt(loginForm.loginPwd.trim())
  }
  await unlockScreenApi(params)
  setStorage('isLock', false)
}
const systemConfig = reactive({
  loginWay: ''
})
const getSystemUserSetting = async () => {
  const res = await getSystemUserSettingApi()
  if (res) {
    appStore.setUserConfig(res.data)
  }
}

const getSystemConfig = async () => {
  const res = await getSystemSettingApi()
  if (res) {
    systemConfig.loginWay = res.data.loginWay
    appStore.setSystemConfig(res.data)
  }
}
getSystemConfig()

const rememberPassword = async () => {
  const rememberPassword: RememberPasswordType | undefined = getStorage('rememberPassword')
  if (rememberPassword) {
    loginForm.userName = rememberPassword.userName
    loginForm.loginPwd = rememberPassword.loginPwd
    remember.value = true
  }
}

// 获取角色信息
const getUserRouterInfo = async () => {
  const res = await getUserRouterInfoApi()
  const routers = res.data || []
  userStore.setRoleRouters(routers as AppCustomRouteRecordRaw[])
  await permissionStore.generateRoutes(routers as AppCustomRouteRecordRaw[]).catch(() => {})
  permissionStore.getAddRouters.forEach((route) => {
    addRoute(route as RouteRecordRaw) // 动态添加可访问路由表
  })
  permissionStore.setIsAddRouters(true)
  await push({ path: redirect.value || permissionStore.addRouters[0].path })
}
onMounted(() => {
  rememberPassword()
  getVerifyCode()
})
const activeName = ref('1')
const handleClick = async (tab: TabsPaneContext) => {
  if (tab.props.name == '1') {
    passwordLoginFormRef.value?.clearValidate()
    await getVerifyCode()
  } else {
    mobileLoginFormRef.value?.clearValidate()
  }
}
const loginForm = reactive<UserLoginType>({
  userName: 'admin',
  loginPwd: '12345678',
  verificationCode: '',
  verificationCodeKey: '',
  mobile: '',
  shortMessageCode: '',
  loginWay: ''
})
const rules = reactive<FormRules<UserLoginType>>({
  userName: [{ required: true, message: '用户名不能为空', trigger: 'blur' }],
  loginPwd: [{ required: true, message: '密码不能为空', trigger: 'blur' }],
  mobile: [
    { required: true, message: '手机号不能为空', trigger: 'blur' },
    {
      pattern: /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/,
      message: '请输入正确的手机号',
      trigger: 'blur'
    }
  ],
  verificationCode: [{ required: true, message: '验证码不能为空', trigger: 'blur' }]
})
const showLoginWay = (loginWay: string) => {
  if (systemConfig.loginWay && systemConfig.loginWay.split(',').includes(loginWay)) {
    return true
  }
}
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('form')
</script>

<template>
  <div class="w-[100%]">
    <h2 class="text-2xl font-bold text-center div-padding">登录</h2>
    <el-tabs v-model="activeName" class="div-padding" @tab-click="handleClick">
      <el-tab-pane label="密码登录" name="1" v-if="showLoginWay('1')">
        <el-form
          ref="passwordLoginFormRef"
          :model="loginForm"
          :rules="rules"
          size="large"
          label-position="top"
          status-icon
          :class="prefixCls"
        >
          <el-row :gutter="20">
            <el-form-item prop="userName" style="width: 100%" class="div-padding">
              <el-input
                :prefix-icon="User"
                v-model="loginForm.userName"
                placeholder="请输入用户名"
              />
            </el-form-item>
          </el-row>
          <el-row :gutter="20">
            <el-form-item prop="loginPwd" style="width: 100%" class="div-padding">
              <el-input
                :prefix-icon="Lock"
                v-model="loginForm.loginPwd"
                type="password"
                placeholder="请输入密码"
              />
            </el-form-item>
          </el-row>
          <el-row :gutter="20" v-if="loginType.openVerificationCode">
            <el-col :span="18">
              <el-form-item prop="verificationCode" style="width: 100%">
                <el-input
                  :prefix-icon="Key"
                  v-model="loginForm.verificationCode"
                  placeholder="请输入验证码"
                />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item prop="loginPwd" style="width: 100%">
                <el-image
                  style="width: 100%; height: 38px"
                  :src="imageSrc"
                  @click="getVerifyCode()"
                />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="20" style="margin-bottom: 10px">
            <el-col :span="18">
              <ElCheckbox v-model="remember" label="记住密码" size="large" />
            </el-col>
            <el-col :span="6" style="text-align: center; display: flex">
              <ElLink type="primary"> 忘记密码? </ElLink>
            </el-col>
          </el-row>
          <el-row :gutter="20">
            <el-col>
              <el-button
                :loading="loading"
                @click="login(passwordLoginFormRef)"
                type="primary"
                style="width: 100%"
                >登录</el-button
              >
            </el-col>
          </el-row>
        </el-form>
      </el-tab-pane>
      <el-tab-pane label="短信登录" name="2" v-if="showLoginWay('2')">
        <el-form
          ref="mobileLoginFormRef"
          :model="loginForm"
          :rules="rules"
          size="large"
          label-position="top"
          status-icon
          :class="prefixCls"
        >
          <el-row :gutter="20">
            <el-col>
              <el-form-item prop="mobile" style="width: 100%">
                <el-input
                  :prefix-icon="Iphone"
                  v-model="loginForm.mobile"
                  placeholder="请输入手机号"
                />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="20">
            <el-col>
              <div style="display: flex">
                <div style="margin-right: 20px; width: 70%">
                  <el-form-item prop="verificationCode">
                    <el-input
                      :prefix-icon="Key"
                      v-model="loginForm.shortMessageCode"
                      placeholder="请输入验证码"
                    />
                  </el-form-item>
                </div>
                <div>
                  <el-form-item>
                    <el-button
                      type="primary"
                      plain
                      @click="getShortMessageVerifyCode(mobileLoginFormRef)"
                      :disabled="remainderTime.countdown"
                      >{{ remainderTime.buttonMessage }}</el-button
                    >
                  </el-form-item>
                </div>
              </div>
            </el-col>
          </el-row>
          <el-row :gutter="20">
            <el-col>
              <el-button
                :loading="loading"
                @click="login(mobileLoginFormRef)"
                type="primary"
                style="width: 100%"
                >登录</el-button
              >
            </el-col>
          </el-row>
        </el-form>
      </el-tab-pane>
    </el-tabs>
    <ElDivider>其他登录</ElDivider>
    <div class="flex justify-between div-padding">
      <Icon
        icon="ant-design:github-filled"
        :size="iconSize"
        class="cursor-pointer ant-icon"
        :color="iconColor"
        :hoverColor="hoverColor"
      />
      <Icon
        icon="ant-design:wechat-filled"
        :size="iconSize"
        class="cursor-pointer ant-icon"
        :color="iconColor"
        :hoverColor="hoverColor"
      />
      <Icon
        icon="ant-design:alipay-circle-filled"
        :size="iconSize"
        :color="iconColor"
        :hoverColor="hoverColor"
        class="cursor-pointer ant-icon"
      />
      <Icon
        icon="ant-design:weibo-circle-filled"
        :size="iconSize"
        :color="iconColor"
        :hoverColor="hoverColor"
        class="cursor-pointer ant-icon"
      />
    </div>
  </div>
</template>
<style lang="less" scoped>
.container {
  display: flex;
  width: 100%;
  flex-direction: column;
}
.div-padding {
  padding-left: 10px;
  padding-right: 10px;
}
.remember-div-margin {
  margin-bottom: 15px;
}
.div-margin {
  margin-bottom: 22px;
}
</style>
